home *** CD-ROM | disk | FTP | other *** search
-
- /*⌐ Copyright 1988-1991 UserLand Software, Inc. All Rights Reserved.*/
-
-
- #include "appletinternal.h"
- #include "ops.h"
- #include "quickdraw.h"
- #include "appletmain.h"
- #include "scrollbar.h"
-
-
-
- #define idvertbar 256
- #define idhorizbar 257
-
-
- static boolean scrollbarpushclip (hdlscrollbar hscrollbar) {
-
- /*
- 11/19/90 DW: patch things up for the table displayer, and perhaps others in
- the future. if the scrollbar is of trivial height, we disable the drawing
- that's about to happen. we were getting one-pixel high scrollbars being
- drawn.
- */
-
- Rect r = (**hscrollbar).contrlRect;
-
- if ((r.bottom - r.top) == 1)
- r.bottom = r.top;
-
- return (pushclip (r));
- } /*scrollbarpushclip*/
-
-
- void validscrollbar (hdlscrollbar hscrollbar) {
-
- register hdlscrollbar h = hscrollbar;
-
- if (h != nil)
- validrect ((**h).contrlRect);
- } /*validscrollbar*/
-
-
- static invalscrollbar (hdlscrollbar hscrollbar) {
-
- register hdlscrollbar h = hscrollbar;
-
- if (h != nil)
- invalrect ((**h).contrlRect);
- } /*invalscrollbar*/
-
-
- boolean pointinscrollbar (Point pt, hdlscrollbar hscrollbar) {
-
- register hdlscrollbar h = hscrollbar;
-
- if (h == nil) /*defensive driving*/
- return (false);
-
- return (pointinrect (pt, (**h).contrlRect));
- } /*pointinscrollbar*/
-
-
- void enablescrollbar (hdlscrollbar hscrollbar) {
-
- register hdlscrollbar h = hscrollbar;
-
- if (h == nil) /*defensive driving*/
- return;
-
- scrollbarpushclip (h);
-
- HiliteControl (h, 0);
-
- /*validscrollbar (h);*/
-
- popclip ();
- } /*enablescrollbar*/
-
-
- void disablescrollbar (hdlscrollbar hscrollbar) {
-
- register hdlscrollbar h = hscrollbar;
-
- if (h == nil) /*defensive driving*/
- return;
-
- scrollbarpushclip (h);
-
- HiliteControl (h, -1);
-
- /*validscrollbar (h);*/
-
- popclip ();
- } /*disablescrollbar*/
-
-
- void activatescrollbar (hdlscrollbar hscrollbar, boolean flactivate) {
-
- if (flactivate)
- enablescrollbar (hscrollbar);
- else
- disablescrollbar (hscrollbar);
- } /*activatescrollbar*/
-
-
- void getscrollbarinfo (hscrollbar, minscroll, maxscroll, current) hdlscrollbar hscrollbar; short *minscroll, *maxscroll, *current; {
-
- register hdlscrollbar h = hscrollbar;
-
- if (h == nil) { /*defensive driving*/
-
- *minscroll = *maxscroll = *current = 0;
-
- return;
- }
-
- *minscroll = GetCtlMin (h);
-
- *maxscroll = GetCtlMax (h);
-
- *current = GetCtlValue (h);
- } /*getscrollbarinfo*/
-
-
- short getscrollbarcurrent (hdlscrollbar hscrollbar) {
-
- short minscroll, maxscroll, current;
-
- getscrollbarinfo (hscrollbar, &minscroll, &maxscroll, ¤t);
-
- return (current);
- } /*getscrollbarcurrent*/
-
-
- void showscrollbar (hdlscrollbar hscrollbar) {
-
- register hdlscrollbar h = hscrollbar;
-
- if (h == nil) /*defensive driving*/
- return;
-
- scrollbarpushclip (h);
-
- ShowControl (h); /*no effect if scrollbar is already visible, according to IM-1*/
-
- popclip ();
-
- /*don't validate the scrollbar rect, ShowControl might not draw it...*/
- } /*showscrollbar*/
-
-
- void hidescrollbar (hdlscrollbar hscrollbar) {
-
- register hdlscrollbar h = hscrollbar;
-
- if (h == nil) /*defensive driving*/
- return;
-
- scrollbarpushclip (h);
-
- HideControl (h);
-
- popclip ();
-
- invalrect ((**h).contrlRect);
- } /*hidescrollbar*/
-
-
- void drawscrollbar (hdlscrollbar hscrollbar) {
-
- register hdlscrollbar h = hscrollbar;
-
- if (h == nil) /*defensive driving*/
- return;
-
- scrollbarpushclip (h);
-
- Draw1Control (h);
-
- popclip ();
-
- validscrollbar (h);
- } /*drawscrollbar*/
-
-
- void displayscrollbar (hdlscrollbar hscrollbar) {
-
- /*
- the caller is saying that we should enable it if there is enough
- material to enable scrolling.
- */
-
- register hdlscrollbar h = hscrollbar;
- short minscroll, maxscroll, current;
-
- if (h == nil) /*defensive driving*/
- return;
-
- getscrollbarinfo (h, &minscroll, &maxscroll, ¤t);
-
- if (minscroll <= maxscroll) /*there's something to scroll to*/
- enablescrollbar (h);
- else
- disablescrollbar (h);
-
- drawscrollbar (h);
- } /*displayscrollbar*/
-
-
- void setscrollbarinfo (hdlscrollbar hscrollbar, short minscroll, short maxscroll, short current) {
-
- /*
- set the bounds of the scrollbar, and its current value.
-
- if the current info agrees with the parameters we do nothing,
- avoiding unpleasant flicker.
-
- disables drawing while setting the values, and draws it when
- all three values have been set. avoids inconsistent displays.
- */
-
- register hdlscrollbar h = hscrollbar;
- short curmin, curmax, curval;
-
- if (h == nil) /*defensive driving*/
- return;
-
- getscrollbarinfo (h, &curmin, &curmax, &curval);
-
- if ((minscroll == curmin) && (maxscroll == curmax) && (current == curval))
- return; /*nothing to do*/
-
- pushemptyclip (); /*disable drawing*/
-
- SetCtlMax (h, maxscroll);
-
- SetCtlMin (h, minscroll);
-
- SetCtlValue (h, current);
-
- popclip ();
-
- displayscrollbar (h);
- } /*setscrollbarinfo*/
-
-
- void setscrollbarminmax (hdlscrollbar hscrollbar, short minscroll, short maxscroll) {
-
- register hdlscrollbar h = hscrollbar;
- short curmin, curmax, curval;
-
- if (h == nil) /*defensive driving*/
- return;
-
- getscrollbarinfo (h, &curmin, &curmax, &curval);
-
- if ((minscroll != curmin) || (maxscroll != curmax)) {
-
- setscrollbarinfo (h, minscroll, maxscroll, curval);
- }
- } /*setscrollbarminmax*/
-
-
- void setscrollbarcurrent (hdlscrollbar hscrollbar, short current) {
-
- register hdlscrollbar h = hscrollbar;
-
- if (h == nil) /*defensive driving*/
- return;
-
- scrollbarpushclip (h);
-
- SetCtlValue (h, current);
-
- popclip ();
- } /*setscrollbarcurrent*/
-
-
- short getscrollbarwidth (void) {
-
- return (16); /*standard Macintosh scrollbars*/
- } /*getscrollbarwidth*/
-
-
- boolean newscrollbar (WindowPtr w, boolean flvert, hdlscrollbar *hscrollbar) {
-
- /*
- create a new scroll bar linked into the control list of the indicated
- window.
-
- we need to know if it is a vertical or horizontal scrollbar so we can
- choose the proper resource template. we use a CDEF that has different
- specs for horiz and vertical scrollbars.
- */
-
- register hdlscrollbar h;
- register short resnum;
-
- if (flvert)
- resnum = idvertbar;
- else
- resnum = idhorizbar;
-
- *hscrollbar = h = GetNewControl (resnum, w);
-
- return (h != nil);
- } /*newscrollbar*/
-
-
- void disposescrollbar (hdlscrollbar hscrollbar) {
-
- register hdlscrollbar h = hscrollbar;
-
- if (h != nil)
- DisposeControl (h);
- } /*disposescrollbar*/
-
-
- void getscrollbarrect (hdlscrollbar hscrollbar, Rect *r) {
-
- register hdlscrollbar h = hscrollbar;
-
- if (h != nil)
- *r = (**h).contrlRect;
- else
- zerorect (r);
- } /*getscrollbarrect*/
-
-
- void setscrollbarrect (hdlscrollbar hscrollbar, Rect r) {
-
- register hdlscrollbar h = hscrollbar;
-
- if (h != nil) {
-
- HideControl (h);
-
- SizeControl (h, r.right - r.left, r.bottom - r.top);
-
- MoveControl (h, r.left, r.top);
- }
- } /*setscrollbarrect*/
-
-
- void scrollbarflushright (Rect r, hdlscrollbar hscrollbar) {
-
- register hdlscrollbar h = hscrollbar;
- register short width;
-
- if (h == nil) /*defensive driving*/
- return;
-
- width = getscrollbarwidth ();
-
- HideControl (h);
-
- SizeControl (h, width, r.bottom - r.top + 2);
-
- MoveControl (h, r.right - width + 1, r.top - 1);
- } /*scrollbarflushright*/
-
-
- void scrollbarflushbottom (Rect r, hdlscrollbar hscrollbar) {
-
- register hdlscrollbar h = hscrollbar;
- register short width;
-
- if (h == nil) /*defensive driving*/
- return;
-
- width = getscrollbarwidth ();
-
- HideControl (h);
-
- SizeControl (hscrollbar, r.right - r.left, width);
-
- MoveControl (hscrollbar, r.left, r.bottom - width + 1);
- } /*scrollbarflushbottom*/
-
-
- boolean findscrollbar (Point pt, WindowPtr w, hdlscrollbar *hscrollbar, short *scrollbarpart) {
-
- *scrollbarpart = FindControl (pt, w, hscrollbar);
-
- return (*hscrollbar != nil);
- } /*findscrollbar*/
-
-
- boolean scrollbarhit (hdlscrollbar hscrollbar, short part, boolean *flup, boolean *flpage) {
-
- /*
- can be called by a routine that tracks a mouse hit in a scroll bar.
-
- return true if it represents a valid scroll action, according to the info
- stored in the scrollbar handle.
-
- return false if the indicated action would move beyond the min or max for
- the scrollbar.
-
- set flup and flpage according to the indicated scrollbar part.
- */
-
- register hdlscrollbar h = hscrollbar;
- short minscroll, maxscroll, current;
-
- if (h == nil) /*defensive driving*/
- return;
-
- getscrollbarinfo (h, &minscroll, &maxscroll, ¤t);
-
- switch (part) {
-
- case inUpButton:
- *flup = false; /*scroll text down*/
-
- *flpage = false;
-
- return (current > minscroll);
-
- case inDownButton:
- *flup = true; /*scroll text up*/
-
- *flpage = false;
-
- return (current < maxscroll);
-
- case inPageUp:
- *flup = false; /*scroll text down*/
-
- *flpage = true;
-
- return (current > minscroll);
-
- case inPageDown:
- *flup = true; /*scroll text up*/
-
- *flpage = true;
-
- return (current < maxscroll);
- } /*switch*/
-
- return (false); /*fell through the switch statement*/
- } /*scrollbarhit*/
-
-
- void resetappscrollbars (appwindow) hdlappwindow appwindow; {
-
- setappwindow (appwindow);
-
- (*app.resetscrollbarscallback) ();
- } /*resetappscrollbars*/
-
-
- void resizeappscrollbars (appwindow) hdlappwindow appwindow; {
-
- if (app.horizscroll || app.vertscroll) {
-
- register hdlappwindow ha = appwindow;
- register short scrollbarwidth;
- Rect rwholewindow = (**ha).windowrect;
- Rect r;
-
- scrollbarwidth = getscrollbarwidth ();
-
- if (app.vertscroll) {
-
- r = rwholewindow;
-
- r.bottom -= scrollbarwidth - 1;
-
- r.top += app.statuspixels; /*leave room for status bar at top of window*/
-
- r.top = (**ha).contentrect.top;
-
- scrollbarflushright (r, (**ha).vertbar);
- }
-
- if (app.horizscroll) {
-
- r = rwholewindow;
-
- r.right -= scrollbarwidth - 2;
-
- r.left -= 1;
-
- scrollbarflushbottom (r, (**ha).horizbar);
- }
- }
- } /*resizeappscrollbars*/
-
-
- void showappscrollbars (appwindow) hdlappwindow appwindow; {
-
- register hdlappwindow ha = appwindow;
-
- if (app.vertscroll)
- showscrollbar ((**ha).vertbar);
-
- if (app.horizscroll)
- showscrollbar ((**ha).horizbar);
- } /*showappscrollbars*/
-
-
- void updateappscrollbars (appwindow) hdlappwindow appwindow; {
-
- register hdlappwindow ha = appwindow;
-
- if (app.vertscroll) {
-
- showscrollbar ((**ha).vertbar);
-
- drawscrollbar ((**ha).vertbar);
- }
-
- if (app.horizscroll) {
-
- showscrollbar ((**ha).horizbar);
-
- drawscrollbar ((**ha).horizbar);
- }
- } /*updateappscrollbars*/
-
-
- void activateappscrollbars (appwindow, flactivate) hdlappwindow appwindow; boolean flactivate; {
-
- register hdlappwindow ha = appwindow;
-
- if (app.vertscroll)
- activatescrollbar ((**ha).vertbar, flactivate);
-
- if (app.horizscroll)
- activatescrollbar ((**ha).horizbar, flactivate);
- } /*activateappscrollbars*/
-
-
- tydirection scrolldirection (boolean flvert, boolean flup) {
-
- register tydirection dir;
-
- if (flvert)
- if (flup)
- dir = up;
- else
- dir = down;
- else
- if (flup)
- dir = left;
- else
- dir = right;
-
- return (dir);
- } /*scrolldirection*/
-
-
- static pascal void apphorizscroll (hdlscrollbar ctrl, short part) {
-
- register tydirection dir;
- boolean flleft, flpage;
-
- if (!scrollbarhit (ctrl, part, &flleft, &flpage))
- return;
-
- dir = scrolldirection (false, flleft);
-
- (*app.scrollcallback) (dir, flpage, 1);
- } /*apphorizscroll*/
-
-
- static pascal void appvertscroll (hdlscrollbar sb, short part) {
-
- register tydirection dir;
- boolean flup, flpage;
-
- if (!scrollbarhit (sb, part, &flup, &flpage))
- return;
-
- dir = scrolldirection (true, flup);
-
- (*app.scrollcallback) (dir, flpage, 1);
- } /*appvertscroll*/
-
-
- void scrollappwindow (boolean flvert, hdlscrollbar sb, short part, Point pt) {
-
- register short oldscrollbarcurrent;
- register short ctscroll;
- tydirection dir;
-
- if (part == inThumb) {
-
- oldscrollbarcurrent = getscrollbarcurrent (sb);
-
- TrackControl (sb, pt, nil);
-
- ctscroll = getscrollbarcurrent (sb) - oldscrollbarcurrent;
-
- dir = scrolldirection (flvert, ctscroll > 0);
-
- (*app.scrollcallback) (dir, false, abs (ctscroll));
- }
- else {
- if (flvert)
- TrackControl (sb, pt, &appvertscroll);
- else
- TrackControl (sb, pt, &apphorizscroll);
- }
- } /*scrollappwindow*/
-
-
- static boolean defaultscroll (tydirection dir, boolean flpage, short ctscroll) {
-
- /*
- if the applet didn't define a scrolling routine, this routine will
- be called to do the scrolling. it implements a very bare-bones way
- of scrolling, that often is just what you want...
- */
-
- register hdlappwindow ha = app.appwindow;
- register short ct = ctscroll;
- register short dh = 0, dv = 0;
- Rect r;
-
- if ((ct == 1) && (!flpage)) { /*it's heuristic time!*/
-
- if (!optionkeydown ()) {
-
- ct = getfontheight (); /*scroll by this (reasonable) amount*/
-
- /*user holds down the option key to get a 2-pixel scroll*/
- }
- }
-
- if (ct % 2) /*it's an odd number*/
- ct++;
-
- r = (**ha).contentrect;
-
- switch (dir) {
-
- case down:
- if (flpage)
- dv = -(r.bottom - r.top);
- else
- dv = -ct;
-
- break;
-
- case up:
- if (flpage)
- dv = r.bottom - r.top;
- else
- dv = ct;
-
- break;
-
- case right:
- if (flpage)
- dh = -(r.right - r.left);
- else
- dh = -ct;
-
- break;
-
- case left:
- if (flpage)
- dh = r.right - r.left;
- else
- dh = ct;
-
- break;
-
- default:
- return (false);
- } /*switch*/
-
- if (dv != 0) {
-
- register short x;
- short vertmin, vertmax, vertcurrent;
-
- getscrollbarinfo ((**ha).vertbar, &vertmin, &vertmax, &vertcurrent);
-
- vertcurrent = (**ha).scrollorigin.v; /*the scrollbar lies, fix it*/
-
- x = vertcurrent + dv;
-
- x = max (x, vertmin);
-
- x = min (x, vertmax);
-
- dv = vertcurrent - x;
-
- vertcurrent = x;
-
- setscrollbarinfo ((**ha).vertbar, vertmin, vertmax, vertcurrent);
-
- (**ha).scrollorigin.v = x;
- }
-
- if (dh != 0) {
-
- register short x;
- short horizmin, horizmax, horizcurrent;
-
- getscrollbarinfo ((**ha).horizbar, &horizmin, &horizmax, &horizcurrent);
-
- horizcurrent = (**ha).scrollorigin.h; /*the scrollbar lies, fix it*/
-
- x = horizcurrent + dh;
-
- x = max (x, horizmin);
-
- x = min (x, horizmax);
-
- dh = horizcurrent - x;
-
- horizcurrent = x;
-
- setscrollbarinfo ((**ha).horizbar, horizmin, horizmax, horizcurrent);
-
- (**ha).scrollorigin.h = x;
- }
-
- if ((dh != 0) || (dv != 0)) {
-
- scrollrect (r, dh, dv);
-
- updateappwindow (ha);
- }
-
- return (true);
- } /*defaultscroll*/
-
-
- void installscroll (void) {
-
- if ((app.scrollcallback == nil) && ((app.horizscroll) || (app.vertscroll)))
- app.scrollcallback = &defaultscroll;
- } /*installscroll*/
-
-
-
-
-